package com.example.youdu.controller;

import com.google.gson.JsonObject;
import im.youdu.sdk.client.AppClient;
import im.youdu.sdk.entity.*;
import im.youdu.sdk.exception.GeneralEntAppException;
import im.youdu.sdk.util.Helper;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/********************************************************************************
 ** author： zhangtianhe
 ** date：2024年08月06日 16:54
 ** description&desc：
 *********************************************************************************/
@Controller
@RequestMapping("")
public class ReceiveController {
    @RequestMapping("/ydapp/a/receive")
    @ResponseBody
    public String receive(HttpServletRequest request) throws IOException {
        int buin = 16129280; // 请填写企业总机号码
        String appName = "第三方认证"; //请填写消息审计名称
        String appId = "sysOrgAssistant"; // 请填写消息审计AppId
        String appToken = "2760qbgag7evb4ag"; //请填写消息审计token
        String appAesKey = "M3KaiF2aUsIE3cOP5ICw/GGu5ZEUSHlip3gb2BFG9dk="; // 请填写消息审计EncodingAesKey
        YDApp ydApp = new YDApp(buin, "", appName, appId, appToken, appAesKey);
        System.out.println("进入验证====："+ydApp.toString());
        //请求参数
        Map<String, String> map = new HashMap<>(3);
        Enumeration<String> keys = request.getParameterNames();
        while (keys.hasMoreElements()) {
            String key = keys.nextElement();
            map.put(key, request.getParameter(key));
        }
        //请求数据体
        InputStream in = request.getInputStream();
        byte[] reqData = Helper.readInputStream(in);
        AppClient appClient = new AppClient(ydApp);
        try {
            //处理接收到的数据体
            handleReceive(map, reqData, appClient, ydApp);
        } catch (GeneralEntAppException e) {
            e.printStackTrace();
        }
        //返回接收成功，不返回接收成功会重复收到消息推送
        return "ok";
    }

    /**
     * 解密消息体
     * @param reqParam  请求参数
     * @param reqData 请求数据体
     * @param appClient 客户端
     * @param app 客户端实体
     * @throws GeneralEntAppException 异常
     * @throws IOException 异常
     */
    private void handleReceive(Map<String, String> reqParam, byte[] reqData, AppClient appClient, YDApp app) throws GeneralEntAppException, IOException {
        String content = Helper.utf8String(reqData);
        JsonObject reqJson = Helper.parseJson(content);
        int buin = Helper.getInt("toBuin", reqJson);
        String appId = Helper.getString("toApp", reqJson);
        String encrypt = Helper.getString("encrypt", reqJson);
        if (buin != app.getBuin()) {
            System.out.println(String.format("[%s][error] from buin %d is unequal local buin %d", app.getAppName(), buin, app.getBuin()));
            return;
        }
        if (!appId.equals(app.getAppId())) {
            System.out.println(String.format("[%s][error] from appId %s is unequal local appId %s", app.getAppName(), appId, app.getAppId()));
            return;
        }
        boolean fromYD = Helper.signatureIsValid(reqParam, app.getToken(), encrypt);
        if (!fromYD) {
            System.out.println(String.format("[%s][error] signature is invalid", app.getAppName()));
            return;
        }
        ReceiveMessage msg = appClient.decrypt(encrypt);
        receive(msg);
    }

    /**
     * 接收到的明文消息
     * @param message 消息类
     */
    private void receive(ReceiveMessage message) {
        try {
            String msgType = message.getMsgType();
            switch (msgType) {
                case Const.Message_App_Type_Event: {
                    EventBody event = message.getAsEvent();
                    System.out.println(String.format("receive app event, appId:%s, operation:%s ", event.getId(), event.getOperation()));
                    break;
                }
                case Const.Message_App_Type_Sms: {
                    SmsBody smsMsg = message.getAsSmsMsg();
                    System.out.println(String.format("receive app sms msg: %s", smsMsg.getContent()));
                    break;
                }
                case Const.Message_Session_Type_Text: {
                    String text = message.getAsTextMsg();
                    System.out.println(String.format("receive text msg: %s", text));
                    break;
                }
                case Const.Message_Session_Type_File: {
                    FileBody appFile = message.getAsFileMsg();
                    System.out.println(String.format("receive file msg, mediaId:: %s, you can download it by AppClient::downloadFileAndSave", appFile.getMediaId()));
                    break;
                }
                case Const.Message_Session_Type_Image: {
                    ImageBody appImg = message.getAsImageMsg();
                    System.out.println(String.format("receive img msg mediaId: %s, you can download it by AppClient::downloadImageAndSave", appImg.getMediaId()));
                    break;
                }
                case Const.Message_Session_Create: {
                    SessionCreateBody sessionCreate = message.getAsSessionCreate();
                    System.out.println(String.format("receive session create event: %s", sessionCreate.toJsonString()));
                    break;
                }
                case Const.Message_Session_Update: {
                    SessionUpdateBody sessionUpdate = message.getAsSessionUpdate();
                    System.out.println(String.format("receive sesion update event: %s", sessionUpdate.toJsonString()));
                    break;
                }
                case Const.Message_Session_Type_Audio: {
                    AudioBody audio = message.getAsAudioMsg();
                    System.out.println(String.format("receive audio msg, mediaId:%s", audio.getMediaId()));
                    break;
                }
                case Const.Message_Session_Type_Complex: {
                    ComplexBody complexBody = message.getAsComplexMsg();
                    System.out.println(String.format("receive complex msg: %s", complexBody.getBody()));
                    break;
                }
                case Const.Message_Session_Type_System: {
                    RecvSystemMsgBody systemMsgBody = message.getAsSystemMsg();
                    System.out.println(String.format("receive system msg: %s", systemMsgBody.getMsg()));
                    break;
                }
                case Const.Message_Session_Type_Broadcast: {
                    RecvBroadcastBody broadcastBody = message.getAsBroadcastMsg();
                    System.out.println(String.format("receive broadcast msg: %s", broadcastBody.getMsg()));
                    break;
                }
                default: {
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
